package val.lemonde;

import java.util.ArrayList;
import java.util.HashSet;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import android.widget.Toast;

public class WidgetReceiverLarge extends AppWidgetProvider {

	public static final String SHOW_CURRENT = "val.lemonde.action.SHOW_CURRENT";

	public static final String SHOW_NEXT = "val.lemonde.action.SHOW_NEXT";

	public static final String UPDATE_WIDGET = "val.lemonde.action.UPDATE_WIDGET";

	private ArrayList<Article> articles;

	private String url = "http://www.lemonde.fr/rss/une.xml";

	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		final int N = appWidgetIds.length;

		for (int i = 0; i < N; i++) {
			Log.d("lemonde", "Widget update:" + appWidgetIds[i]);
			int appWidgetId = appWidgetIds[i];
			// Lien vers la page courante d'lemonde
			//int id = appWidgetManager.getAppWidgetInfo(appWidgetId).initialLayout;
			RemoteViews views = new RemoteViews(context.getPackageName(),
					R.layout.widget_lemonde_large);
			// On defini les action sur les elements du widget
			this.defined_intent(context, views, appWidgetIds);

			views.setTextViewText(R.id.widget_message, "Mise à jour en cours");
			views.setTextViewText(R.id.widget_update_texte, "0 news");
			views.setTextViewText(R.id.widget_next_texte, "0/0");
			views.setViewVisibility(R.id.widget_new, View.INVISIBLE);
			views.setViewVisibility(R.id.widget_web, View.INVISIBLE);
			views.setViewVisibility(R.id.widget_image, View.INVISIBLE);
			views.setImageViewBitmap(R.id.widget_image, BitmapFactory
					.decodeResource(context.getResources(), R.drawable.vide));
			appWidgetManager.updateAppWidget(appWidgetId, views);
			Log.d("lemonde", "widget telechargement");
			if (i == 0) {
				new GetArticleWidget(context, appWidgetIds).execute(url);
			}
		}
	}

	public void updateArticles(ArrayList<Article> articlesBackground,
			Context context, int[] appWidgetIds) {

		int newArticle = 0;

		AppWidgetManager appWidgetManager = AppWidgetManager
				.getInstance(context);
		RemoteViews views = new RemoteViews(context.getPackageName(),
				R.layout.widget_lemonde_large);
		this.defined_intent(context, views, appWidgetIds);

		for (int i = 0; i < appWidgetIds.length; i++) {
			Log.d("lemonde", "Widget update article:" + appWidgetIds[i]);
			int appWidgetId = appWidgetIds[i];
			try {
				articles = articlesBackground;
				if (articles == null || articles.size() == 0)
					throw new Exception("Erreur de telechargement");

				Toast.makeText(context, "lemonde widget à jour",
						Toast.LENGTH_SHORT).show();

				if (i == 0) {
					// on rcherche si ils sont nouveaux
					newArticle = this.get_new_articles(articles, context);
					Log.d("lemonde", "download_artciles:" + articles.size());
				}
			} catch (Exception e) {
				String error = e.toString() + "\n" + e.getStackTrace()[0]
						+ "\n" + e.getStackTrace()[1];
				Log.e("lemonde", "Error widget " + error);
			} finally {

				if (articles == null) {
					articles = new ArrayList<Article>();
				}
				if (i == 0) {
					this.get_datas(context).save_widget_article(articles);
					this.get_datas(context).save_widget_posi(0);
					this.get_datas(context).save_widget_new(newArticle);
				}
				this.defined_article(views, context, 0);
				appWidgetManager.updateAppWidget(appWidgetId, views);
			}
		}
	}

	private void defined_intent(Context context, RemoteViews views,
			int[] appWidgetIds) {

		// update du widget
		Intent intent = new Intent(context, WidgetReceiverLarge.class);
		// intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
		// intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
		intent.setAction(UPDATE_WIDGET);
		intent.putExtra("IDS", appWidgetIds);
		PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
				intent, PendingIntent.FLAG_UPDATE_CURRENT // no flags
				);
		views.setOnClickPendingIntent(R.id.widget_update, pendingIntent);

		// show current article
		intent = new Intent(context, WidgetReceiverLarge.class);
		intent.setAction(SHOW_CURRENT);
		pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		views.setOnClickPendingIntent(R.id.widget_mes, pendingIntent);

		// show next article
		intent = new Intent(context, WidgetReceiverLarge.class);
		intent.setAction(SHOW_NEXT);
		pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		views.setOnClickPendingIntent(R.id.widget_next, pendingIntent);
	}

	private void defined_article(RemoteViews views, Context context, int posi) {
		if (articles.size() != 0) {
			views.setTextViewText(R.id.widget_message, articles.get(posi)
					.getTitle());

			this.get_datas(context).save_widget_posi(posi);
			views.setTextViewText(R.id.widget_next_texte, (posi + 1) + "/"
					+ articles.size());
			views.setTextViewText(R.id.widget_update_texte,
					this.get_datas(context).get_widget_new() + " news");
			if (articles.get(posi).isWidgetNew())
				views.setViewVisibility(R.id.widget_new, View.VISIBLE);
			else
				views.setViewVisibility(R.id.widget_new, View.INVISIBLE);
			if (!articles.get(posi).isMobileLink())
				views.setViewVisibility(R.id.widget_web, View.VISIBLE);
			else
				views.setViewVisibility(R.id.widget_web, View.INVISIBLE);
			Bitmap bit = this.get_datas(context).getImageCache()
					.getBitmapForFile(articles.get(posi).getMediaLink());
			if (bit != null) {
				Log.d("lemonde", "Widget View image");
				views.setViewVisibility(R.id.widget_image, View.VISIBLE);
				views.setImageViewBitmap(R.id.widget_image, bit);
			} else {
				views.setViewVisibility(R.id.widget_image, View.INVISIBLE);
				views.setImageViewBitmap(R.id.widget_image,
						BitmapFactory.decodeResource(context.getResources(),
								R.drawable.vide));
			}

		} else {
			views.setTextViewText(R.id.widget_message, "Erreur de mise à jour");
			views.setTextViewText(R.id.widget_update_texte, "0 news");
			views.setTextViewText(R.id.widget_next_texte, "0/0");
			views.setViewVisibility(R.id.widget_new, View.INVISIBLE);
			views.setViewVisibility(R.id.widget_web, View.INVISIBLE);
			views.setViewVisibility(R.id.widget_image, View.INVISIBLE);
			views.setImageViewBitmap(R.id.widget_image, BitmapFactory
					.decodeResource(context.getResources(), R.drawable.vide));
		}
	}

	public void onReceive(Context context, Intent intent) {
		// v1.5 fix that doesn't call onDelete Action
		final String action = intent.getAction();

		Log.d("lemonde", "Action=" + action);
		if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
			final int appWidgetId = intent.getExtras().getInt(
					AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);
			if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
				this.onDeleted(context, new int[] { appWidgetId });
			}
		} else if (SHOW_CURRENT.equals(action)) {
			articles = this.get_datas(context).get_widget_article();
			int posi = this.get_datas(context).get_widget_posi();
			if (posi < articles.size()) {
				if (articles.get(posi).isMobileLink()) {
					Intent in = new Intent(context, ActivityPage.class);
					in.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					in.putExtra("articles", articles);
					in.putExtra("article", articles.get(posi));
					in.putExtra("position", posi);
					context.startActivity(in);
					this.get_datas(context).add_articles_lues(articles.get(posi).getLinkUri());
				} else {
					Intent in = new Intent(Intent.ACTION_VIEW);
					in.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					Uri u = Uri.parse(articles.get(posi).getLinkUri());
					in.setData(u);
					context.startActivity(in);
				}
			}
			RemoteViews views = new RemoteViews(context.getPackageName(),
					R.layout.widget_lemonde_large);
			// On met l'artcile courant lu
			this.defined_article(views, context, posi);

			ComponentName thisWidget = new ComponentName(context,
					WidgetReceiverLarge.class);
			AppWidgetManager manager = AppWidgetManager.getInstance(context);
			// On redefini les action sur les elements du widget
			this.defined_intent(context, views,
					manager.getAppWidgetIds(thisWidget));
			manager.updateAppWidget(thisWidget, views);
		} else if (SHOW_NEXT.equals(action)) {
			articles = this.get_datas(context).get_widget_article();
			int posi = this.get_datas(context).get_widget_posi();

			if ((posi + 1) == articles.size())
				posi = 0;
			else
				posi++;
			Log.d("lemonde", "position widget;" + posi);
			Log.d("lemonde", "save_articles:" + articles.size());
			RemoteViews views = new RemoteViews(context.getPackageName(),
					R.layout.widget_lemonde_large);
			this.defined_article(views, context, posi);

			ComponentName thisWidget = new ComponentName(context,
					WidgetReceiverLarge.class);
			AppWidgetManager manager = AppWidgetManager.getInstance(context);
			// On redefini les action sur les elements du widget
			this.defined_intent(context, views,
					manager.getAppWidgetIds(thisWidget));
			// int[] temp = manager.getAppWidgetIds(thisWidget);
			// for(int z=0;z<temp.length;z++)
			// Log.d("lemonde","intent update of:"+temp[z]);
			manager.updateAppWidget(thisWidget, views);
			// appWidgetManager.updateAppWidget(appWidgetId, views);
		} else if (UPDATE_WIDGET.equals(action)) {
			int[] ids = intent.getIntArrayExtra("IDS");
			this.onUpdate(context, AppWidgetManager.getInstance(context), ids);
		} else {
			super.onReceive(context, intent);
		}
	}

	public void onDisabled(Context context) {
		super.onDisabled(context);
		Log.d("lemonde", "disabled widget");
	}

	public void onEnabled(Context context) {
		super.onEnabled(context);
		Log.d("lemonde", "enabled widget");
	}

	public void onDeleted(Context context, int[] appWidgetIds) {
		super.onDeleted(context, appWidgetIds);
		Log.d("lemonde", "deleted widget");
	}

	private int get_new_articles(ArrayList<Article> articles, Context c) {
		// on parcours les anciens artciles
		ArrayList<Article> ar = this.get_datas(c).get_widget_article();
		HashSet<String> urls = new HashSet<String>();
		for (Article a : ar) {
			urls.add(a.getUri());
		}
		// si nouveau
		int count = 0;
		for (Article a : articles) {
			if (urls.contains(a.getUri())) {
				a.setWidgetNew(false);
			} else {
				a.setWidgetNew(true);
				count++;
			}
		}
		return (count);
	}

	public SharedDatas get_datas(Context c) {
		SharedDatas datas = SharedDatas.shared;
		if (datas == null)
			return (new SharedDatas(c));
		datas.setContext(c);
		return datas;
	}

	private class GetArticleWidget extends AsyncTask<String, Void, Void> {

		private ArrayList<Article> articlesBackground;

		private Context context;

		private int[] appWidgetIds;

		private SharedDatas shared;

		public GetArticleWidget(Context c, int[] Ids) {
			shared = WidgetReceiverLarge.this.get_datas(c);
			context = c;
			appWidgetIds = Ids;
		}

		// can use UI thread here
		protected void onPreExecute() {
			articlesBackground = null;
		}

		// automatically done on worker thread (separate from UI thread)
		protected Void doInBackground(String... args) {
			try {
				RssDownload d = new RssDownload(args[0]);
				d.get_rss_articles();
				articlesBackground = d.getArticles();
				Log.d("lemonde", "widget telechargement termine");
				shared.getImageCache().clearMemoryCache();
				for (Article art : articlesBackground) {
					shared.getImageCache().addBitmapToCache(art.getMediaLink());
				}
			} catch (Exception e) {
				String error = e.toString() + "\n" + e.getStackTrace()[0]
						+ "\n" + e.getStackTrace()[1];
				Log.e("lemonde", error);
			}
			return (null);

		}

		protected void onPostExecute(Void result) {
			WidgetReceiverLarge.this.updateArticles(articlesBackground, context,
					appWidgetIds);
		}

	}

}
